/*******************************************************************************
 *    版权信息   ： @copyright Copyright 2014-2021 chnenergy All Right Reserved
 *    作   者   ： hhz
 *    版   本   ： 1.1
 *    创建时间   ：2024/4/13
 *    最后修改日期   ： 2024/4/13
 *    最后修改人员   ： hhz
 ******************************************************************************/
package io.github.houhanzhi.hhregistry.controller;

import com.alibaba.fastjson.JSON;
import io.github.houhanzhi.hhregistry.cluster.Cluster;
import io.github.houhanzhi.hhregistry.cluster.Server;
import io.github.houhanzhi.hhregistry.cluster.Snapshort;
import io.github.houhanzhi.hhregistry.model.InstanceMeta;
import io.github.houhanzhi.hhregistry.service.HHRegistryService;
import io.github.houhanzhi.hhregistry.service.RegistryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * Rest Controller for registry service
 **/
@RestController
@Slf4j
public class HHRegistryController {

    @Autowired
    RegistryService registryService;

    @Autowired
    Cluster cluster;

    @RequestMapping("/register")
    public InstanceMeta register(@RequestParam String service, @RequestBody InstanceMeta instance) {
        log.info(" ===> register {} @ {}", service, instance);
        checkLeader();
        return registryService.register(service, instance);
    }


    @RequestMapping("/unregister")
    public InstanceMeta unregister(@RequestParam String service, @RequestBody InstanceMeta instance) {
        log.info(" ===> unregister {} @ {}", service, instance);
        checkLeader();
        return registryService.unregister(service, instance);
    }

    @RequestMapping("/getAllInstances")
    public List<InstanceMeta> getAllInstances(@RequestParam String service) {
        log.info(" ===> getAllInstances {}", service);
        return registryService.getAllInstances(service);
    }

    @RequestMapping("/renew")
    public long renew(@RequestParam String service, @RequestBody InstanceMeta instance) {
        log.info(" ===> renew {}", service);
        return registryService.renew(instance, service);
    }

    @RequestMapping("/renews")
    public long renews(@RequestParam String service, @RequestBody InstanceMeta instance) {
        log.info(" ===> renew {}", service);
        return registryService.renew(instance, service.split(","));
    }

    @RequestMapping("/version")
    public Long version(@RequestParam String service) {
        log.info(" ===> version {}", service);
        return registryService.version(service);
    }

    @RequestMapping("/versions")
    public Map<String, Long> versions(@RequestParam String service) {
        log.info(" ===> versions {}", service);
        return registryService.versions(service.split(","));
    }

    @RequestMapping("/info")
    public Server info() {
        log.info(" ===> info: {}", cluster.self());
        return cluster.self();
    }

    @RequestMapping("/cluster")
    public List<Server> cluster() {
        log.info(" ===> cluster: {}", cluster.getServers());
        return cluster.getServers();
    }

    @RequestMapping("/leader")
    public Server leader() {
        log.info(" ===> leader: {}", cluster.leader());
        return cluster.leader();
    }

    @RequestMapping("/setLeader")
    public Server setLeader() {
        cluster.self().setLeader(true);
        log.info(" ===> setLeader: {}", cluster.self());
        return cluster.self();
    }


    @RequestMapping("/snapshot")
    public Snapshort snapshot() {
        return HHRegistryService.snapshot();
    }

    private void checkLeader() {
        if (!cluster.self().isLeader()) {
            throw new RuntimeException("current server is not a leader. the leader is " + cluster.leader().getUrl());
        }
    }

    public static void main(String[] args) {
        final InstanceMeta instance = InstanceMeta.http("127.0.0.1", 8081)
                .addParams(Map.of("env", "dev", "tag", "RED"));
        log.debug(JSON.toJSONString(instance));

    }

}
